package jp.seraph.same.controller;

import jp.seraph.jsmf.motion.DefaultMotion;
import jp.seraph.jsmf.motion.DefaultMotionElement;
import jp.seraph.jsmf.motion.DefaultMotionSession;
import jp.seraph.jspf.pose.Pose;
import jp.seraph.jspf.utils.PoseUtil;
import jp.seraph.same.core.EditorMotionSelector;
import jp.seraph.same.model.PoseCollectionModel;
import jp.seraph.same.model.PoseModel;

public class DefaultPoseController implements PoseController {
    public DefaultPoseController() {

    }

    /**
     * initializeメソッドに渡すものと一緒に呼び出すコンストラクタ。<br>
     * 自動でinitializeメソッドの呼び出しを行う。
     *
     * @param aModel
     * @param aSelector
     * @param aDefaultPose
     *            リセット時にセットされるべきポーズ。 初期化にも使用される
     */
    public DefaultPoseController(PoseCollectionModel aModel, EditorMotionSelector aSelector, PoseUtil aPoseUtil, Pose aDefaultPose) {
        this.initialize(aModel, aSelector, aPoseUtil, aDefaultPose);
    }

    /**
     * 初期化メソッド
     *
     * @param aModel
     * @param aSelector
     * @param aDefaultPose
     *            リセット時にセットされるべきポーズ。 初期化にも使用される
     */
    public void initialize(PoseCollectionModel aModel, EditorMotionSelector aSelector, PoseUtil aPoseUtil, Pose aDefaultPose) {
        mModel = aModel;
        mSelector = aSelector;
        mDefaultPose = aDefaultPose;
        mPoseUtil = aPoseUtil;
        this.reset();
        this.updatePose();
    }

    private PoseCollectionModel mModel;
    private EditorMotionSelector mSelector;
    private Pose mDefaultPose;
    private PoseUtil mPoseUtil;

    /**
     *
     * @see jp.seraph.same.controller.PoseController#reset()
     */

    public void reset() {
        mModel.getSelectedPose().setPose(mDefaultPose);
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#copyLeftToRight()
     */

    public void copyLeftToRight() {
        PoseModel tModel = mModel.getSelectedPose();
        tModel.setPose(mPoseUtil.getLeftToRightCopiedPose(tModel.createPose()));
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#copyRightToLeft()
     */

    public void copyRightToLeft() {
        PoseModel tModel = mModel.getSelectedPose();
        tModel.setPose(mPoseUtil.getRightToLeftCopiedPose(tModel.createPose()));
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#reversePoseAsMirror()
     */

    public void reversePoseAsMirror() {
        PoseModel tModel = mModel.getSelectedPose();
        tModel.setPose(mPoseUtil.getMirrorPose(tModel.createPose()));
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#savePose(java.lang.String,
     *      jp.seraph.jspf.pose.Pose)
     */

    public void savePose(String name, Pose pose) {
        mModel.setPose(name, pose);
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#removePose(java.lang.String)
     */

    public void removePose(String aName) {
        mModel.removePose(aName);
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#selectJoint(java.lang.String)
     */

    public void selectJoint(String jointName) {
        mModel.getSelectedPose().selectJoint(jointName);
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#selectPose(java.lang.String)
     */

    public void selectPose(String poseName) {
        mModel.selectPose(poseName);
        this.setPose(mModel.getPose(poseName).createPose());
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#setJointAngle(java.lang.String,
     *      double)
     */

    public void setJointAngle(String jointName, double degree) {
        PoseModel tModel = mModel.getSelectedPose();
        tModel.getJointModel(jointName).setJointAngleAsDegree(degree);
        this.setPose(tModel.createPose());
    }

    /**
     *
     * @see jp.seraph.same.controller.PoseController#setPose(jp.seraph.jspf.pose.Pose)
     */

    public void setPose(Pose pose) {
        mSelector.setMotion(new DefaultMotion(new DefaultMotionSession("Session", new DefaultMotionElement("Element", pose))));
    }

    public void updatePose() {
        this.setPose(mModel.getSelectedPose().createPose());
    }
}
